home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
071-080
/
amok71
/
nodefilter1.2a
/
nodefilter.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
12KB
|
403 lines
(* ------------------------------------------------------------------------
:Program. NodeFilter
:Contents. generate filtered Fido-BBS-List from NodeList
:Author. Kai Bolay [kai]
:Address. Hoffmannstraße 168
:Address. D-7250 Leonberg 1
:History. v0.1 [kai] 15-May-91 (initial)
:History. v0.2 [kai] 19-May-91 (- Host-bug)
:History. v0.3 [kai] 20-May-91 (+ speed, + Flags, ...)
:History. v1.0 [kai] 22-May-91 (Flags OK, variable output, rework)
:History. v1.1 [kai] 23-May-91 (cosmetic, bug fixes, time)
:History. v1.2 [kai] 24-May-91 (2.0 pattern-matching if available
more chars, new address-output)
:History. v1.2a [kai] 24-Apr-92 recompiled
:Copyright. © 1991-92 by Kai Bolay
:Copyright. distribution allowed for non-comercial purposes
:Language. Oberon
:Translator. AMIGA OBERON v2.25d, A+L AG
:Imports. StringOps [bne], PatMatch [kai]/Bernd Preusing
:Remark. created for Jörg Henner
------------------------------------------------------------------------ *)
MODULE NodeFilter;
IMPORT
fs: FileSystem, a:Arguments, ng: NoGuru, io, so: StringOps, Break,
pat: PatMatch, d: Dos;
CONST
Version = "\[1mNodeFilter\[21;3m v1.2a\[23;32m by Kai Bolay\[0m\n\n\o"
"$VER: NodeFilter 1.2a (24-Apr-92)\r\n";
ticksPerMinute = d.ticksPerSecond * 60;
ticksPerHour = ticksPerMinute * 60;
ticksPerDay = ticksPerHour * 24;
CM = 0;
MO = 1;
HST = 2;
XA = 3;
V42B = 4;
V32B = 5;
V21 = 6;
V22 = 7;
V32 = 8;
V42 = 9;
MNP = 10;
XX = 11;
XB = 12;
XW = 13;
XR = 14;
PEP = 15;
Funct = 0;
Name = 1;
City = 2;
Sysop = 3;
Phone = 4;
Baud = 5;
Flags = 6;
Zone = 7;
Net = 8;
Node = 9;
Num = 10;
StrLen = 150;
VAR
NodeName, BBSName: ARRAY 30 OF CHAR;
NodeFile, BBSFile: fs.File;
NodeOpen, BBSOpen: BOOLEAN;
Input, Output: ARRAY 256 OF CHAR;
Flag: ARRAY 30 OF CHAR;
Now, Then: d.Date;
Desc: ARRAY Num OF ARRAY 10 OF CHAR;
Check: ARRAY Num OF BOOLEAN;
Pat: ARRAY Num OF ARRAY StrLen OF CHAR;
Aux: ARRAY Num OF ARRAY StrLen OF SHORTINT;
Str: ARRAY Num OF ARRAY StrLen OF CHAR;
Width: ARRAY Num OF INTEGER;
NewZone, NewNet, Ok, Prompt, Stat, NewOS, Addr: BOOLEAN;
Comma, Pos, Line, Len, i, j: INTEGER;
CurZone, CurNet: ARRAY 5 OF CHAR;
CurFlags, WantFlags: LONGSET;
li: LONGINT;
ZoneCount, RegionCount, HostCount, HubCount, DownCount,
PvtCount, HoldCount, NodeCount, BBSCount: INTEGER;
PROCEDURE GetStr (k: INTEGER);
BEGIN
Comma := so.FindChar (Input, ',', Pos);
IF Comma = -1 THEN
io.WriteString ("\nLine"); io.WriteInt (Line, 5);
io.WriteString (": expected "); io.WriteString (Desc[k]); io.WriteLn;
HALT (20);
END; (* IF *)
so.SubString (Input, Str[k], Pos, Comma-Pos);
Pos := Comma+1;
END GetStr;
PROCEDURE GetFlags (VAR FlagSet: LONGSET);
VAR
Found: BOOLEAN;
PROCEDURE TestFlag (s: ARRAY OF CHAR; f: INTEGER);
BEGIN
IF (NOT Found) AND (Flag = s) THEN
INCL (FlagSet, f); Found := TRUE;
END; (* IF *)
END TestFlag;
BEGIN
FlagSet := LONGSET {};
LOOP
Comma := so.FindChar (Input, ',', Pos);
IF Comma = -1 THEN EXIT END;
so.SubString (Input, Flag, Pos, Comma-Pos);
Pos := Comma+1;
Found := FALSE;
TestFlag ("CM", CM );
TestFlag ("MO", MO );
TestFlag ("HST", HST );
TestFlag ("XA", XA );
TestFlag ("V42B", V42B);
TestFlag ("V32B", V32B);
TestFlag ("V21", V21 );
TestFlag ("V22", V22 );
TestFlag ("V32", V32 );
TestFlag ("V42", V42 );
TestFlag ("MNP", MNP );
TestFlag ("XX", XX );
TestFlag ("XB", XB );
TestFlag ("XW", XW );
TestFlag ("XR", XR );
TestFlag ("PEP", PEP );
IF NOT Found THEN
(* Unknown Flag *)
END; (* IF *)
END; (* LOOP *)
END GetFlags;
PROCEDURE Display (k: INTEGER);
VAR
len: INTEGER;
BEGIN
IF Width[k] > 1 THEN
len := so.Length (Output);
so.Append (Output, Str[k]);
Output[len+Width[k]-1] := 0X;
so.AppendBlanks (Output, len+Width[k]);
END; (* IF *)
END Display;
PROCEDURE WriteCount (str: ARRAY OF CHAR; cnt: INTEGER);
BEGIN
io.WriteString ("processed"); io.WriteInt (cnt, 6);
io.WriteString (str); io.WriteLn;
END WriteCount;
BEGIN
Desc[Zone] := "Zone";
Desc[Net] := "Net";
Desc[Node] := "Node";
Desc[Name] := "Name";
Desc[City] := "City";
Desc[Sysop] := "Sysop";
Desc[Phone] := "Phone";
Desc[Baud] := "Baud";
Desc[Flags] := "Flags";
Desc[Funct] := "Funct";
NodeOpen := FALSE; BBSOpen := FALSE; Stat := FALSE;
NewOS := d.dos.lib.version >= 37;
Prompt := d.IsInteractive (io.in);
d.DateStamp (Then);
io.WriteString (Version);
IF a.NumArgs() # 2 THEN
io.WriteString ("Usage: NodeFilter NodeList/A BBSList/A");
IF (a.NumArgs() = 1) THEN
a.GetArg (1, NodeName);
IF NodeName = "?" THEN
io.WriteString ("\nNodeList: input file, a valid Fido-nodelist\n");
io.WriteString ("BBSList: output file, created by NodeFilter\n");
io.WriteString ("\nUse this program to filter the nodelist for interesting\n");
io.WriteString ("informations. Use AmigaDOS-style pattern-matching!");
END; (* IF *)
END; (* IF *)
HALT (20);
END; (* IF *)
a.GetArg (1, NodeName);
ng.Assert (fs.Open (NodeFile, NodeName, FALSE),
"Unable to open NodeList!");
NodeOpen := TRUE;
a.GetArg (2, BBSName);
ng.Assert (fs.Open (BBSFile, BBSName, TRUE),
"Unable to open BBSList!");
BBSOpen := TRUE;
IF Prompt THEN
io.WriteString ("Use Amiga-DOS pattern-matching. <RETURN> for all!\n");
io.WriteString ("Width defines output-format. <RETURN> -> No Output\n");
io.WriteString ("Enter Flags seperated by commas (e.g. 'MO,HST')\n\n");
END; (* IF *)
i := 0;
REPEAT
IF Prompt THEN
so.Concat ("
", Desc[i], Output);
so.Append (Output, ":"); so.AppendBlanks (Output, 15);
END; (* IF *)
IF i # Flags THEN
IF Prompt THEN
so.Append (Output, "
Pattern:
"); io.WriteString (Output);
END; (* IF *)
io.ReadString (Pat[i]);
j := so.FindChar (Pat[i], ';', 0);
IF j # -1 THEN Pat[i][j] := 0X END;
so.CutBlanks (Pat[i]);
Check[i] := (Pat[i][0] # 0X) AND (Pat[i] # "*") AND
(Pat[i] # "#?");
IF Check[i] THEN
IF NewOS THEN
COPY (Pat[i], Input);
ng.Assert (d.ParsePatternNoCase (Input, Pat[i], StrLen) # -1,
"pattern error!");
ELSE
ng.Assert (pat.CmplPat (Pat[i], Aux[i]), "pattern error!");
END; (* IF *)
END; (* IF *)
ELSE
IF Prompt THEN
so.Append (Output, "
Flags:
"); io.WriteString (Output);
END; (* IF *)
io.ReadString (Input);
j := so.FindChar (Input, ';', 0);
IF j # -1 THEN Input[j] := 0X END;
so.CutBlanks (Input);
Check[Flags] := Input # "";
IF Check[Flags] THEN
so.AppendChar (Input, ',');
GetFlags (WantFlags);
END; (* IF *)
END; (* IF *)
IF (i # Node) AND (i # Net) AND (i # Zone) THEN
IF Prompt THEN
io.WriteString ("
Width:
");
END; (* IF *)
io.ReadString (Input);
j := so.FindChar (Input, ';', 0);
IF j # -1 THEN Input[j] := 0X END;
so.CutBlanks (Input);
ng.Assert (so.StrToIntOk (Input, li), "integer error!");
Width[i] := SHORT (li);
END; (* IF *)
INC (i);
IF Prompt THEN io.WriteLn END;
UNTIL (i = Num);
IF Prompt THEN
io.WriteString ("
Address:
");
END; (* IF *)
io.ReadString (Input);
j := so.FindChar (Input, ';', 0);
IF j # -1 THEN Input[j] := 0X END;
so.CutBlanks (Input);
ng.Assert ((Input[0] = 'y') OR (Input[0] = 'n'), "only y/n!");
Addr := Input[0] = 'y';
Stat := TRUE;
d.DateStamp (Then);
Line := 0;
LOOP
REPEAT
IF NOT fs.ReadString (NodeFile, Input) THEN EXIT END;
INC (Line);
IF Line MOD 100 = 0 THEN io.Write ('.') END;
UNTIL Input[0] # ';';
j := so.Length (Input);
IF j > 1 THEN Input[j-1] := ',' END;
Pos := 0;
GetStr (Funct);
NewZone := FALSE;
NewNet := FALSE;
IF Str[Funct] = "" THEN
INC (NodeCount);
ELSIF Str[Funct] = "Zone" THEN
INC (ZoneCount);
NewZone := TRUE;
NewNet := TRUE;
ELSIF Str[Funct] = "Region" THEN
INC (RegionCount);
NewNet := TRUE;
ELSIF Str[Funct] = "Host" THEN
INC (HostCount);
NewNet := TRUE;
ELSIF Str[Funct] = "Hub" THEN
INC (HubCount);
ELSIF Str[Funct] = "Down" THEN
INC (DownCount);
ELSIF Str[Funct] = "Pvt" THEN
INC (PvtCount);
ELSIF Str[Funct] = "Hold" THEN
INC (HoldCount);
ELSE
io.WriteString ("\nLine"); io.WriteInt (Line, 5);
io.WriteString (": Eh, what's '"); io.WriteString (Str[Funct]);
io.WriteString ("' ???"); HALT (20);
END; (* IF *)
GetStr (Node);
IF NewZone THEN COPY (Str[Node], CurZone) END;
IF NewNet THEN COPY (Str[Node], CurNet); Str[Node] := "0" END;
COPY (CurZone, Str[Zone]);
COPY (CurNet, Str[Net]);
i := Name;
REPEAT
GetStr (i);
INC (i);
UNTIL i = Flags;
(* whole Flags! *)
so.SubString (Input, Str[i], Pos, so.Length (Input)-Pos-1);
GetFlags (CurFlags);
Ok := TRUE; i := 0;
REPEAT
IF i = Flags THEN
Ok := ((NOT Check[i]) OR (CurFlags * WantFlags = WantFlags));
ELSE
IF NewOS THEN
Ok := ((NOT Check[i]) OR d.MatchPatternNoCase (Pat[i], Str[i]));
ELSE
Ok := ((NOT Check[i]) OR pat.Match (Pat[i], Aux[i], Str[i]));
END; (* IF *)
END; (* IF *)
INC (i);
UNTIL (i = Num) OR NOT Ok;
IF Ok THEN
Output := "";
i := 0;
REPEAT
IF (i # Node) AND (i # Net) AND (i # Zone) THEN
Display (i);
END; (* IF *)
INC (i);
UNTIL i = Num;
IF Addr THEN
so.AppendChar (Output, '(');
so.Append (Output, Str[Zone]);
so.AppendChar (Output, ':');
so.Append (Output, Str[Net]);
so.AppendChar (Output, '/');
so.Append (Output, Str[Node]);
so.AppendChar (Output, ')');
END; (* IF *)
ng.Assert (fs.WriteString (BBSFile, Output),
"Error writing BBSFile!");
INC (BBSCount);
END; (* IF *)
END; (* LOOP *)
CLOSE
d.DateStamp (Now);
IF NodeOpen THEN
ng.Assert (fs.Close (NodeFile), "Unable to close NodeList!");
END; (* IF *)
IF BBSOpen THEN
ng.Assert (fs.Close (BBSFile), "Unable to close BBSFile!");
END; (* IF *)
IF Stat THEN
io.WriteString ("\n\n
Statistics:
\n\n");
WriteCount (" Zones", ZoneCount);
WriteCount (" Regions", RegionCount);
WriteCount (" Hosts", HostCount);
WriteCount (" Hubs", HubCount);
WriteCount (" Downs", DownCount);
WriteCount (" Pvts", PvtCount);
WriteCount (" Holds", HoldCount);
WriteCount (" Nodes", NodeCount);
io.WriteString ("It took");
li := ((Now.tick - Then.tick) +
(Now.minute - Then.minute) * ticksPerMinute +
(Now.days - Then.days) * ticksPerDay) DIV d.ticksPerSecond;
io.WriteInt (li, 4); io.WriteString (" secs to scan");
io.WriteInt (Line, 6); io.WriteString (" lines =>");
IF li # 0 THEN
io.WriteInt (Line DIV li, 4);
io.WriteString (" lines per second...\n");
ELSE
io.WriteString (" ---\n");
END; (* IF *)
io.WriteString ("list contains"); io.WriteInt (BBSCount, 6);
io.WriteString (" BBSs!\n\n");
ELSE
io.WriteLn; io.WriteLn;
END; (* IF *)
END NodeFilter.